<?php
/**
 * RMS自动升级程序
 * 自动升级步骤：
 * 1.检查版本，并生成一个临时队列
 * 2.下载新程序
 * 3.解压缩
 * 4.覆盖文件
 * @author AileenGuan <aileenguan@gmail.com>
 */

require_once('../global.php');

class AutoUpdate
{
	/**
	 * 自动更新服务器的路径
	 *
	 */
	const UPDATE_PATH = 'https://rms-aileenguan.googlecode.com/svn/trunk';

	const UPDATE_SERVER = 'rms-aileenguan.googlecode.com';

	protected $buildList = array();
	
	protected $currentVersion = ''; //当前升级的版本
	
	protected $version = ''; //当前系统版本

	/**
	 * 记录是否有错误存在
	 *
	 * @var boolean
	 */
	protected $err = 0;

	/**
	 * 记录返回信息
	 *
	 * @var string
	 */
	protected $str = '';
	
	public function __construct($action = '')
	{
		$this->version = readover(D_P . 'data/version.dat'); //读取当前的版本号
		if (!empty($action)) {
			if(method_exists($this, $action))
			{
				$this->$action();
			}
			else 
			{
				$this->showMsg('调用了无效的方法');
			}
		}
		
		
	}

	/**
	 * 更新服务器连接测试
	 *
	 */
	public function connectTest()
	{
		$fp = fsockopen(self::UPDATE_SERVER, 80, $errno, $errstr, 3);
		if (!$fp) {
			$this->err = 1;
			$this->showMsg('无法连接远程更新服务器，请检查此服务器外网访问是否通畅。');
			return ;
		} else {
			$this->showMsg('1');
		}
	}

	/**
	 * 获取更新列表，判断是否需要更新
	 *
	 */
	public function judgeVersion()
	{
		$buildList = file_get_contents(self::UPDATE_PATH  . "version.txt"); //从服务器上获取版本列表
		$buildList = explode("\r\n", $buildList);
		$needUpdate = 0;
		foreach ($buildList as $build)
		{
			if (empty($build)) {
				continue;
			}
			elseif ($build > $this->version) //找到了需要更新的版本
			{
				$this->buildList[] = $build;
				$needUpdate++;
			}
		}
		if ($needUpdate == 0) {
			$this->showMsg('0');
			//$this->str = '当前系统已经是最新版本，无需更新';
			return ;
		} else {
			$buildList = serialize($this->buildList);
			file_put_contents(D_P . 'data/update.list', $buildList);
			$this->showMsg(end($this->buildList));
		}
	}
	
	/**
	 * 执行
	 *
	 */
	public function getUpdate()
	{
		$string = readover(D_P . 'data/update.list');
		$buildList = unserialize($string);
		$current = current($buildList);
		
		if (empty($current)) {
			
			//说明已经更新完了
			exit('OK');
			return;
		} else {
			//exit(': ' . $current);
		}
		
		$this->currentVersion = $current;
		$this->download();
		$this->unzip();
		$this->querySQL();
		
		writeover(D_P . 'data/version.dat', $this->currentVersion);
		
		array_shift($buildList);
		writeover(D_P . 'data/update.list', serialize($buildList));
		
		$this->showMsg($current);
	}

	public function download()
	{
		$fp = fopen(self::UPDATE_PATH . $this->currentVersion . '.zip', 'rb');
		if (!$fp) {
			$this->showMsg('无法下载版本更新包。');
		}
		$data = '';
		while (!feof($fp)) {
			$data .= fread($fp, 4096);
		}
		file_put_contents(D_P . 'data/' . $this->currentVersion . '.zip', $data);
		//$this->showMsg('OK');
	}

	public function unzip()
	{
		$error = unpackZip(D_P . 'data/' . $this->currentVersion . '.zip', D_P);
		if ($error) {
			//$this->showMsg("OK");
		} else {
			$this->showMsg('解压缩文件失败');
		}
	}
	
	protected function querySQL()
	{
		if (!file_exists(D_P . 'data/' . $this->currentVersion . '.sql')) {
			return ;
		}
		
		$string = readover(D_P . 'data/' . $this->currentVersion . '.sql');
		//$string = file_get_contents(self::UPDATE_PATH . $current . '.sql');
		if (!empty($string)) {
			global $db;
			$db->query($string);
		}
	}
	
	protected function showMsg($msg)
	{
		echo $msg;
		exit;
	}
}

function unpackZip($zipfile, $targetDir)
{
	if ($zip = zip_open($zipfile)) {
		if ($zip) {
			if (!is_dir($targetDir) && !mkdir($targetDir)) { //目标目录不存在，且创建失败
				return false;
			}
			//mkdir($dir.$file);
			while ($zip_entry = zip_read($zip)) {
				if (zip_entry_open($zip,$zip_entry,"r")) {
					$buf = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));
					$dir_name = dirname(zip_entry_name($zip_entry));
					if ($dir_name != ".") {
						$dir_op = $targetDir;
						foreach ( explode("/",$dir_name) as $k) {
							$dir_op = $dir_op . $k;
							if (is_file($dir_op)) unlink($dir_op);
							if (!is_dir($dir_op)) mkdir($dir_op);
							$dir_op = $dir_op . "/" ;
						}
					}
					$fp=fopen($targetDir . zip_entry_name($zip_entry), "w");
					fwrite($fp,$buf);

					fclose($fp);
					zip_entry_close($zip_entry);
				}
				else
				{
					return false;
				}
			}
			zip_close($zip);
		}
	}
	else
	{
		return false;
	}

	return true;
}


$update = new AutoUpdate($_GET['action']);
//$update->unzip();

?>